#coding=utf-8
#一個簡單實用，可以上走下走的TreeNode物件


class TreeNode:
    '''簡單的通用樹結構
    get時直接讀取sub和parent就好了，但是修改結構(如delete和insert)就必須要使用隨付函式'''
    def __init__(self):
        self.parent = None #記錄父節點
        self.sub = [] #記錄子節點順序為手動排序順序

    def getTreeTop(self):
        '''回傳頂層節點'''
        if self.parent:
            return self.parent.getTreeTop()
        return self

    def unlinkParent(self):
        '''如果parent存在，將兩者斷開'''
        if self.parent:
            self.parent.sub.remove(self)
            self.parent = None

    def recuAllSub(self, func):
        '''對所有子節點(含自身)執行某func函式，func可以接受一個TreeNode物件
        執行順序是從頁節點一路返回'''
        if self.sub:
            for node in self.sub:
                node.recuAllSub(func)
        func(self)

    def insertSub(self, index, sub):
        '''在index的位置插入子節點，注意index從0計算'''
        if sub in self.sub:
            #如果sub在自身的self.sub中，則分為兩種狀況
            #一種index在自身前面，一種index在自身後面
            currentIndex = self.sub.index(sub) #先計算當前索引位置
            if index == currentIndex:
                return #索引位置完全相同，不用做任何變更。
            elif index < currentIndex: #目標索引位置在當前索引位置前面時，沒有必要用特殊處理，一般插入即可
                pass
            else:
                #如果目標索引位置在當前索引位置後面，則會因為先斷開與parent(即自身)的聯結，當前索引位置-1
                #而使企圖插入的索引位置比預想時多出1，必須要因應這種變化做出補償
                index = index-1
        sub.unlinkParent() #先斷開原本的聯結
        sub.parent = self
        self.sub.insert(index, sub)

    def appendSub(self, sub):
        '''加入新的子節點'''
        return self.insertSub(len(self.sub) + 1, sub)

    def setParent(self, parent):
        '''設定新的parent'''
        return parent.appendSub(self)


